﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;
using Reborn_WorldServer.App1AppHandler.Spells.Interfaces;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_PoisonBuff : Buff, IInstantCast
    {
        private int baseDamageRank1 = 100; // (Level 1)
        private int baseTicksRank1 = 7;

        private int baseDamageRank2 = 190; // (Level 9)
        private int baseTicksRank2 = 9;

        private int baseDamageRank3 = 350; // (Level 23)
        private int baseTicksRank3 = 12;

        private int calcTotalDamage = 0;
        private int baseTicks = 0;

        private double increment = 0;

        public Spell_PoisonBuff()
            : base()
        {
            minutesLeft = 1;
            ticksLeft = 16;
            spellTimer.Interval = 2000;
        }

        override protected void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            ticksLeft--;

            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

            lock (lockitem.LockObj)
            {
                //This buff has been removed, do nothing (this can occur if the buff gets overwritten exactly when this timer fires)
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                if (TargetCreatureBase.HP < 1)
                {
                    RemoveSpell(true, false);
                    return;
                }
                
                //Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
                List<Character> CharactersWithin8 = new List<Character>();
                MapItem CurrentMapItem = null;
                foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin8)
                {
                    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY)
                        CurrentMapItem = mapitem;

                    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 8 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 8)
                    {
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character)
                                CharactersWithin8.Add((Character)creaturebase);
                        }
                    }
                }
                int damage = System.Convert.ToInt32(Math.Floor(increment * (ticksLeft + 1)));

                TargetCreatureBase.InflictDamage(damage, CastingCharacterID);
                TargetCreatureBase.Update_Character();

                Managers.GameHandler.TrySendMessage(CastingCharacterID, "Your poison damages " + TargetCreatureBase.Name + " (" + damage.ToString() + ")", "damage");
                TargetCreatureBase.SendMessage("You are poisoned! (" + damage.ToString() + ")", "spelldamage");

                if (TargetCreatureBase.HP < 1)
                {
                    if (TargetCreatureBase is Creature)
                        CurrentMapItem.CreaturesBases.Remove(TargetCreatureBase);

                    Managers.GameHandler.TrySendMessage(CastingCharacterID, "You have slain " + TargetCreatureBase.Name, "slay");
                    TargetCreatureBase.SendMessage("You have been SLAIN!", "slain");

                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.AddMapItem(CurrentMapItem);
                    }

                    //This spell killed the creature so this buff has already been removed, do nothing.
                    return;
                }
                else
                {
                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.UpdateCreatureBaseHp(TargetCreatureBase);
                    }
                }
                if (ticksLeft == 0)
                {
                    RemoveSpell(true, true);
                    return;
                }
                else
                    spellTimer.Start();
            }
            
        }


        public void InstantCast(CreatureBase castingCreature, CreatureBase targetCreatureBase, SpellIcon _spellIcon, int castLevel)
        {
            if (InitializeInstantCast(castingCreature, targetCreatureBase, _spellIcon, castLevel, true) == false)
                return;

            int timeRemaining = -1;

            if (_spellIcon.Name.IndexOf("Rank 3") > -1)
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank3, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank3;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank3;
            }
            else if (_spellIcon.Name.IndexOf("Rank 2") > -1)
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank2, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank2;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank2;
            }
            else
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank1, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank1;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank1;
            }

            ticksLeft = timeRemaining;

            //Increment * ticks = damage to do for current tick.
            increment = ((calcTotalDamage / baseTicks) * 2) / (baseTicks + 1);
            if (increment == 0)
                increment = 1;

            spellTimer.Start();

            Managers.GameHandler.TrySendMessage(CastingCharacterID, "You poison " + TargetCreatureBase.Name, "spelloffense");

            if (TargetCreatureBase.ID != CastingCharacterID && TargetCreatureBase is Character)
                TargetCreatureBase.SendMessage("You have been poisoned!", "spelloffense");

            TargetCreatureBase.buffManager.UpdateBuffs();

            //foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
            //{
            //    if (Math.Abs(mapitem.MapX - targetCreatureBase.MapX) <= 4 && Math.Abs(mapitem.MapY - targetCreatureBase.MapY) <= 4)
            //    {
            //        foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
            //        {
            //            if (creatureBase is Character)
            //            {
            //                Character charToUpdate = (Character)creatureBase;
            //                charToUpdate.AddCreatureBase(targetCreatureBase);
            //            }
            //        }
            //    }
            //}
        }

        override public void Resume(CreatureBase targetCreatureBase, SpellIcon _spellIcon, int timeRemaining, int castLevel, int castCharacterID, int castInt, int castWis, int optionalValue, string xmlData)
        {
            base.Resume(targetCreatureBase, _spellIcon, timeRemaining, castLevel, castCharacterID, castInt, castWis, optionalValue, xmlData);

            if (_spellIcon.Name.IndexOf("Rank 3") > -1)
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank3, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank3;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank3;
            }
            else if (_spellIcon.Name.IndexOf("Rank 2") > -1)
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank2, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank2;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank2;
            }
            else
            {
                calcTotalDamage = SkillManager.AdjustForCombat(castLevel, baseDamageRank1, CastingCreatureInt);
                calcTotalDamage = targetCreatureBase.CalculateGetSpellDamagePerResists(calcTotalDamage, spellIcon.Skill, .5M);
                baseTicks = baseTicksRank1;
                if (timeRemaining == -1)
                    timeRemaining = baseTicksRank1;
            }

            ticksLeft = timeRemaining;

            //Increment * ticks = damage to do for current tick.
            increment = ((calcTotalDamage / baseTicks) * 2) / (baseTicks + 1);
            if (increment == 0)
                increment = 1;

            spellTimer.Start();

            Managers.GameHandler.TrySendMessage(CastingCharacterID, "You poison " + TargetCreatureBase.Name, "spelloffense");
            
            if (TargetCreatureBase.ID != castCharacterID && TargetCreatureBase is Character)
                TargetCreatureBase.SendMessage("You have been poisoned!", "spelloffense");

            TargetCreatureBase.buffManager.UpdateBuffs();
        }


        
    }
}
